#include "stdafx.h"
#include "DebugZones.h"
#include "appwindowsenums.h"


CRITICAL_SECTION g_cs;

BOOL APIENTRY DllMain(HANDLE hInstance, DWORD  dwReason, LPVOID lpReserved)
{
	FUNC_ENTRY(L"hInstance = 0x%08X, dwReason = 0x%08X", hInstance, dwReason);
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        // Disable thread creation/deletion calls into this function
        DisableThreadLibraryCalls((HMODULE)hInstance);
		// Register with debug subsystem
		RETAILREGISTERZONES((HMODULE)hInstance);
        InitializeCriticalSection(&g_cs);
        break;
    }
    case DLL_PROCESS_DETACH:
    {
        DeleteCriticalSection(&g_cs);
        break;
    }
    default:
        break;
    }    
	FUNC_EXIT(L"TRUE");
	return TRUE;
}

//Gets zeroed for each EnumWindowsCall
int g_windowCount = 0;

//Use fixed array for simplicity and speed as will get called regularly
LPWSTR g_windowDetails[MaxNoApps];

//LPWSTR windowDetails[MaxNoApps];
HANDLE g_winHandles[MaxNoApps];

//Function prototype for Callback
int WndEnumProc(HWND hwnd, LPARAM lParam);


 extern "C" AppWindowsEnums_API void Init()
{
	FUNC_ENTRY(L"void");
	EnterCriticalSection(&g_cs);
	for (int i=0; i<MaxNoApps; i++) 
		g_windowDetails[i] = new TCHAR[MAX_CHAR];
	LeaveCriticalSection(&g_cs);
	FUNC_EXIT(L"");
}

extern "C"  AppWindowsEnums_API void DeInit()
{
	FUNC_ENTRY(L"void");
	EnterCriticalSection(&g_cs);
	for (int i=0; i<MaxNoApps; i++) 
		delete[] g_windowDetails[i];
	LeaveCriticalSection(&g_cs);
	FUNC_EXIT(L"");
}

extern "C" AppWindowsEnums_API int GetWindowCount( )
{
	FUNC_ENTRY(L"void");
	FUNC_EXIT(L"Window Count = %d", g_windowCount);
	return g_windowCount;
}


extern "C" AppWindowsEnums_API HANDLE GetWindowDetails( WCHAR * winText, int index)
{
	FUNC_ENTRY(L"winText = %s  index = %d", winText, index);
    HANDLE hRet = INVALID_HANDLE_VALUE;
	if (index < g_windowCount)
	{
        EnterCriticalSection(&g_cs);
		wcscpy(winText, g_windowDetails[index]);
        hRet = g_winHandles[index];
        LeaveCriticalSection(&g_cs);
	}
	FUNC_EXIT(L"window handle = %d", hRet);
	return hRet;
}


extern "C" AppWindowsEnums_API void GetAppWindows ()
{
	FUNC_ENTRY(L"void");
	g_windowCount=0;
	EnumWindows(WndEnumProc, 137);
    return ;
}

//EnumWindows Callback. Place each Window Text and its handle into the windowDetails and the winHandles  arrays respectively
int WndEnumProc(HWND hwnd, LPARAM lParam)
{
	FUNC_ENTRY(L"lpParam = 0x%08X", lParam);
    int iRet = -1;
	int currentWindowCount=0;
	//Check if top level winow of app.
    HWND hwndParent;
    hwndParent = GetParent(hwnd);
    if (hwndParent != (HWND)0)
        return lParam +1;

	int len = GetWindowTextLengthW(hwnd);
	
	EnterCriticalSection(&g_cs);
	g_windowCount++;
	
	if (len <2)
	{
		//Ignore some spurious subwindows.
		g_windowCount--;
		LeaveCriticalSection(&g_cs);
		//return (int)lParam;

	}
	else if (g_windowCount > MaxNoApps)
	{
		//Linit to number of apps to display
		g_windowCount--;
		LeaveCriticalSection(&g_cs);
		//return (int)lParam;
	}
	
	else
	{
		currentWindowCount = g_windowCount;
		LeaveCriticalSection(&g_cs);

		g_winHandles[currentWindowCount - 1] = hwnd;

		DWORD dwTextLength = 	GetWindowText(hwnd, g_windowDetails[currentWindowCount - 1], MAX_CHAR);

		if (dwTextLength == 0)
		{
			LOGMSG(ZONE_ERROR, L"ERROR: GetWindow Text failed for 0x%08X", hwnd);
			g_winHandles[currentWindowCount - 1] = NULL;
			g_windowCount--;
		}

		else
		{
			//Ignore certain Windows
			bool discard = false;

			if (wcsncmp(L"About Windows Embedded Compact 2013", g_windowDetails[g_windowCount - 1], wcslen(L"About Windows Embedded Compact 2013")) == 0)
				discard = true;
			else if (wcsncmp(L"TaskBar", g_windowDetails[g_windowCount - 1], wcslen(L"TaskBar")) == 0)
				discard = true;
			else if (wcsncmp(L"Desktop", g_windowDetails[g_windowCount - 1], wcslen(L"Desktop")) == 0)
				discard = true;
			else if (wcsncmp(L"Default Ime", g_windowDetails[g_windowCount - 1], wcslen(L"Default Ime")) == 0)
				discard = true;

			if (discard)
			{
				//If window text is DISCARD then don't display
				wsprintf(g_windowDetails[g_windowCount - 1], L"DISCARD");
				//return (int)lParam;
			}
		}
	}
	FUNC_EXIT(L"lParam=0x%08X", (int)lParam);
    return (int)lParam;
}